package com.h2.ref.server.user.dao;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.h2.ref.server.user.model.User;

public class UserDaoInMem implements IUserDao {
   
   private static final Logger LOG = LoggerFactory.getLogger(
         UserDaoInMem.class);
   
   ////
   
   private Map<Integer, User> _users = new LinkedHashMap<Integer, User>();
   
   private Integer _nextId = 0;
   
   ////
   ////
   
   public void init() {
      
      if (getUsers() == null) {
         return;
      }
      for (User user : getUsers().values()) {
         if(user.getId() == null) {
            user.setId(getNextId());
            setNextId(getNextId() + 1);
         }
      }
   }
   
   public void setUserList(Collection<User> users) {
      for (User user : users) {
         addUser(user);
      }
   }
   
   public Collection<User> getUserList() {
      return getUsers().values();
   }
   
   public synchronized User addUser(User user) {
      if(user.getId() == null) {
         while (getUsers().containsKey(getNextId())) {
            setNextId(getNextId() + 1);
         }
         user.setId(getNextId());
      }
      else if(getUsers().containsKey(user.getId())) {
         LOG.error("ID already exists.");
         return getUsers().get(user.getId());
      }
      getUsers().put(user.getId(), user);
      
      return user;
   }

   @Override
   public void update(User user) {
      User storedUser = getUsers().get(user.getId());
      
      //name
      if (user.getName() != null) {
         storedUser.setName(user.getName());
      }
      
      //password
      if (user.getName() != null) {
         storedUser.setName(user.getName());
      }
      
      //isActive
      if (user.isActive() != null) {
         storedUser.setActive(user.isActive());
      }
      
      if (user.getUserDetails() != null) {
         //email
         if (user.getUserDetails().getEmail() != null) {
            storedUser.getUserDetails().setEmail(
                  user.getUserDetails().getEmail());
         }
         
         //birthday
         if (user.getUserDetails().getBirthday() != null) {
            storedUser.getUserDetails().setBirthday(
                  user.getUserDetails().getBirthday());
         }
      }
      
      //roles
      if (user.getRoles() != null) {
         storedUser.setRoles(user.getRoles());
      }
   }

   @Override
   public void delete(User user) {
      getUsers().remove(user.getId());
   }

   @Override
   public User findByUserName(String username) {
      for (User user : getUsers().values()) {
         if(username.equalsIgnoreCase(user.getName())) {
            return user;
         }
      }
      return null;
   }

   @Override
   public User findByUserId(Integer userId) {
      return getUsers().get(userId);
   }

   @Override
   public User findByEmail(String email) {
      for (User user : getUsers().values()) {
         if(email.equalsIgnoreCase(user.getUserDetails().getEmail())) {
            return user;
         }
      }
      return null;
   }

   /**
    * @return the users
    */
   public Map<Integer, User> getUsers() {
      return _users;
   }

   /**
    * @param users the users to set
    */
   public void setUsers(Map<Integer, User> users) {
      _users = users;
   }

   /**
    * @return the nextId
    */
   public Integer getNextId() {
      return _nextId;
   }

   /**
    * @param nextId the nextId to set
    */
   public void setNextId(Integer nextId) {
      _nextId = nextId;
   }

}
